﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Admin.Core.Service.sys.OLLog/SysLogServiceImpl 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       SysLogServiceImpl
* 创建时间：  2025/6/4 15:52:01
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using AspNetCoreRateLimit;
using Mapster;
using MapsterMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using SSPivot.Admin.Core.DbModel.sys;
using SSPivot.Admin.Core.Repository;
using SSPivot.Admin.Core.Service.sys.OLLog.Dto;
using SSPivot.AspNetCore.Services;
using SSPivot.Common;
using SSPivot.Common.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SSPivot.Admin.Core.Service.sys.OLLog
{
    /// <summary>
    /// 登录日志服务
    /// </summary>
    public class SysLogServiceImpl : ApplicationService, ISysLogService
    {
        #region 接口注入
        public IHttpContextAccessor HttpContextAccessor { get; set; }
        public ISSPivotRepository<sys_login_log> SysLoginLogRepository { get; set; }
        public SysLogServiceImpl(IHttpContextAccessor httpContextAccessor,
            ISSPivotRepository<sys_login_log> loginlogRes)
        {
            HttpContextAccessor = httpContextAccessor;
            SysLoginLogRepository = loginlogRes;
        }
        #endregion

        #region 服务
        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<(List<SysLoginLogDto>, PageResult)> GetPageAsync(QuerySysLoginLogRequest model, PageResult page)
        {
            var data = await SysLoginLogRepository.QueryNoTracking(this.BuildSearch(model),this.BuildSort(model), page).ToListAsync();
            return (data.Adapt<List<SysLoginLogDto>>(), page);
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<long> AddAsync(SysLoginLogDto model)
        {
            if (model.IP.IsNull())
                model.IP = ServerRequestHelper.GetRemoteIP();

            var entity = Mapper.Map<sys_login_log>(model);

            string ua = HttpContextAccessor?.HttpContext?.Request?.Headers?.UserAgent;
            if (ua.IsNotNullOrEmpty())
            {
                var client = UAParser.Parser.GetDefault().Parse(ua);
                var device = client.Device.Family;
                device = device.ToLower() == "other" ? "" : device;
                entity.Browser = client.UA.Family;
                entity.Os = client.OS.Family;
                entity.Device = device;
                entity.BrowserInfo = ua;
            }
            model.Id = IdGeneratorHelper.IdSnowflake();
            await SysLoginLogRepository.AddAsync(entity);

            return entity.Id;
        }
        #endregion

        #region private
        private Expression<Func<sys_login_log, bool>> BuildSearch(QuerySysLoginLogRequest model)
        {
            Expression<Func<sys_login_log, bool>> whereCondition = e => true;

            if (model.Creator.IsNotNullOrWhiteSpace())
                whereCondition = whereCondition.And(e => e.Creator.Contains(model.Creator));
            if (model.Status.HasValue)
                whereCondition = whereCondition.And(x => x.Status == model.Status);
            if (model.IP.IsNotNullOrWhiteSpace())
                whereCondition = whereCondition.And(e => e.IP.Contains(model.IP));
            if (model.SDate.HasValue)
                whereCondition = whereCondition.And(e => e.CreatedTime > model.SDate);

            if (model.EDate.HasValue)
            {
                var date = model.EDate.Value.AddDays(1);
                whereCondition = whereCondition.And(e => e.CreatedTime < date);
            }

            return whereCondition;
        }

        private Dictionary<Expression<Func<sys_login_log, dynamic>>, SortType> BuildSort(QuerySysLoginLogRequest model)
        {
            var orderBy = new Dictionary<Expression<Func<sys_login_log, dynamic>>, SortType>();

            orderBy.Add(e => e.Id, SortType.Desc);
            return orderBy;
        }

        #endregion
    }
}
